﻿using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc;
using WebAPI.Common.Extensions;
using WebAPI.Common.Attributes;
using Newtonsoft.Json;
using Microsoft.EntityFrameworkCore;
using WebAPI.DataAccess;
using WebAPI.Services;
using Microsoft.Extensions.Logging.Abstractions;
using Newtonsoft.Json.Linq;
using WebAPI.Util;
using InParkRedemptionAPI.DataAccess;
using RapidSalesAdminPortalAPI.DataAccess;

namespace WebAPI.Filters
{
    public class LogActionAttribute : ActionFilterAttribute
    {
        private ILogger<LogActionAttribute> _logger;
        private ISystemLogService _logService;
        private string actionArgs = string.Empty;
        private string LoginName = string.Empty;
        //注入一个日志服务
        public LogActionAttribute(ILogger<LogActionAttribute> logger, ISystemLogService logService)
        {
            _logger = logger;
            _logService = logService;
            //_logService = new SystemLogService();
        }

        public override void OnActionExecuting(ActionExecutingContext context)
        {
            string? url = context.HttpContext.Request.Path.Value;
            string argument = JsonConvert.SerializeObject(context.ActionArguments);


            if (argument.Contains("Password"))
            {

                JObject model = JObject.Parse(argument);
                if (model != null)
                {
                    var Name = model.Children().FirstOrDefault().Path;
                    JObject parentModel = (JObject)model[Name];
                    //JObject parentModel = JObject.Parse(argument);
                    if (parentModel != null)
                    {
                        if (argument.Contains("Username"))
                            LoginName = parentModel["Username"].ToString();
                     
                        parentModel["Password"] = MD5Encryption.Encrypt(parentModel["Password"].ToString());
                        if (argument.Contains("ConfirmPassword"))
                        {
                            parentModel["ConfirmPassword"] = MD5Encryption.Encrypt(parentModel["ConfirmPassword"].ToString());
                        }
                        argument = JsonConvert.SerializeObject(model);
                    }
                }

            }

            string? controllerName = context.Controller.GetType().FullName;
            string? actionName = context.ActionDescriptor.DisplayName;

            this.actionArgs = argument;

            //this._logger.LogInformation($"url={url}---argument={argument}", $"OriginalClassName:{controllerName ?? ""},OriginalMethodName:{actionName ?? ""},Remark:{nameof(LogActionAttribute)}.{nameof(OnActionExecuting)}");
        }

        public override void OnResultExecuted(ResultExecutedContext context)
        {
            try
            {
                //判断标签是在方法上
                if (context.ActionDescriptor is not ControllerActionDescriptor controllerActionDescriptor)
                {
                    return;
                }
                    

                LogAttribute? logAttribute = controllerActionDescriptor.MethodInfo.GetCustomAttributes(inherit: true)
                  .FirstOrDefault(a => a.GetType().Equals(typeof(LogAttribute))) as LogAttribute;
                context.HttpContext.GetCurrentUserId();

                if (logAttribute is null) return;

                string controllerName = context.RouteData.Values["Controller"].ToString();

                string actionName = context.RouteData.Values["Action"].ToString();

                FrIpSystemLog logInfo = new FrIpSystemLog
                {
                    LogTypeId = logAttribute.LogType.ToString(),
                    //SessionId = context.HttpContext.GetTokenStr(),
                    SessionId = context.HttpContext.GetSessionID(),
                    ClientHostIp = context.HttpContext.GetClientIp(),
                    FunctionModuleId = !string.IsNullOrWhiteSpace(logAttribute.Module) ? logAttribute.Module : controllerName,
                    SubFunctionModuleId = !string.IsNullOrWhiteSpace(logAttribute.SubModule) ? logAttribute.SubModule : actionName,
                    Description = logAttribute.Description,
                    RequestScript = string.Empty, 
                    Response = "response -> hello.",
                    ResponseCode = context.HttpContext.Response.StatusCode.ToString(),
                    CreateUser = context.HttpContext.GetCurrentUserId(),
                    CreateDate = DateTime.Now,
                    Timestamp = DateTime.Now,
                    PlatformLoginName = string.IsNullOrWhiteSpace(context.HttpContext.GetPlatformLoginName()) ? LoginName : context.HttpContext.GetPlatformLoginName(),
                };

                if (logAttribute.IsSaveResponseData)
                {
                    if (context.Result is ContentResult result && result.ContentType == "application/json")
                    {
                        logInfo.Response = result.Content?.Replace("\r\n", "").Trim();
                    }
                    if (context.Result is JsonResult result2)
                    {
                        logInfo.Response = result2.Value?.ToString();
                    }

                    if (context.Result is ObjectResult result3)
                    {
                        logInfo.Response = JsonConvert.SerializeObject(result3.Value);
                    }

                }


                if (logAttribute.IsSaveRequestData)
                {
                    //logInfo.RequestScript = context.HttpContext.GetRequestValue(context.HttpContext.Request.Method);
                    logInfo.RequestScript = this.actionArgs;
                }
                this._logService.CreateSystemLog(logInfo);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"operation log recorded an error:{ex.Message}");
            }

        }
    }
}

